package middlewares

import (
	"msems/controller"
	"msems/pkg/jwt"
	"strings"

	"go.uber.org/zap"

	"github.com/gin-gonic/gin"
)

//// JWTAuthMiddleware 基于JWT的认证中间件 两个token版
//func JWTAuthMiddleware() func(c *gin.Context) {
//	return func(c *gin.Context) {
//		// 客户端携带Token有三种方式 1.放在请求头 2.放在请求体 3.放在URI
//		// 这里假设Token放在Header的Authorization中，并使用Bearer开头
//		// 这里的具体实现方式要依据你的实际业务情况决定
//		authHeader := c.Request.Header.Get("Authorization")
//		if authHeader == "" {
//			controller.ResponseError(c, controller.CodeNeedLogin)
//			c.Abort()
//			return
//		}
//		// 按空格分割
//		parts := strings.SplitN(authHeader, " ", 2)
//		if !(len(parts) == 2 && parts[0] == "Bearer") {
//			controller.ResponseError(c, controller.CodeInvalidToken)
//			c.Abort()
//			return
//		}
//		// parts[1]是获取到的tokenString，我们使用之前定义好的解析JWT的函数来解析它
//		mc, ok := jwt.ParseToken(parts[1])
//		// 如果aToken 有错或者超出期限
//		if ok != nil {
//			// 取出rToken
//			rToken := c.Request.Header.Get("rToken")
//			// 进行刷新,当access token 是过期错误并且refresh token 没有过期就创建一个新的
//			newAToken, newRToken, err := jwt.RefreshToken(parts[1], rToken)
//			if err != nil {
//				controller.ResponseError(c, controller.CodeInvalidToken)
//				c.Abort()
//				return
//			}
//			//如果解析的新aToken有问题
//			mc, ok = jwt.ParseToken(newAToken)
//			if ok != nil {
//				controller.ResponseError(c, controller.CodeInvalidToken)
//				c.Abort()
//				return
//			}
//			// 将当前请求的userid信息保存到请求的上下文c上
//			c.Set(controller.CtxUserIDKey, mc.UserID)
//			c.Next() // 后续的处理函数可以用过c.Get(ctxUserIDKey)来获取当前请求的用户信息
//			//返回新的token
//			controller.ResponseSuccess(c, gin.H{
//				"accessToken":  newAToken,
//				"refreshToken": newRToken,
//			})
//			return
//		}
//		// 将当前请求的userid信息保存到请求的上下文c上
//		c.Set(controller.CtxUserIDKey, mc.UserID)
//		c.Next() // 后续的处理函数可以用过c.Get(ctxUserIDKey)来获取当前请求的用户信息
//	}
//}

// JWTAuthMiddleware JWTAuthMiddleware基于JWT的认证中间件
func JWTAuthMiddleware() func(c *gin.Context) {
	return func(c *gin.Context) {
		//客户端携带Token有三种方式1.放在请求头2.放在请求体3.放在URI
		//这里假设Token放在Header的Authorization中，并使用Bearer开头
		//这里的具体实现方式要依据你的实际业务情况决定
		authHeader := c.Request.Header.Get("Authorization")
		if authHeader == "" {
			controller.ResponseError(c, controller.CodeNeedLogin)
			c.Abort()
			return
		}
		//按空格分割
		parts := strings.SplitN(authHeader, " ", 2)
		if !(len(parts) == 2 && parts[0] == "Bearer") {
			controller.ResponseError(c, controller.CodeInvalidToken)
			c.Abort()
			return
		}
		//parts[1]是获取到的tokenString，我们使用之前定义好的解析JWT的函数来解析它
		mc, err := jwt.ParseToken(parts[1])
		if err != nil {
			zap.L().Error("jwt.ParseToken(parts[1]) err", zap.Error(err))
			controller.ResponseError(c, controller.CodeInvalidToken)
			c.Abort()
			return
		}
		//将当前请求的userid信息保存到请求的上下文c上
		c.Set(controller.CtxUserIDKey, mc.UserID)
		c.Next() //后续的处理函数可以用过c.Get(ctxUserIDKey)来获取当前请求的用户信息
	}
}
